package com.gdust.hzx.manager.service.impl;

import com.gdust.hzx.manager.mapper.ProductDetailsMapper;
import com.gdust.hzx.manager.mapper.ProductMapper;
import com.gdust.hzx.manager.mapper.ProductSkuMapper;
import com.gdust.hzx.manager.service.ProductService;
import com.gdust.hzx.model.dto.product.ProductDto;
import com.gdust.hzx.model.entity.product.Product;
import com.gdust.hzx.model.entity.product.ProductDetails;
import com.gdust.hzx.model.entity.product.ProductSku;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * ClassName: ProductServiceImpl
 * Package: com.gdust.spzx.manager.service.impl
 * Description:商品服务实现类
 * <p>
 * spu: 商品名称或通用属性（如品牌、型号等）
 * sku: 商品的具体参数（如颜色、规格等）
 *
 * @Author syun
 * @Create 2024/12/22 17:11
 * @Version 1.0
 */
@Service
public class ProductServiceImpl implements ProductService {
    //注入产品类的mapper
    @Autowired
    private ProductMapper productMapper;

    //注入商品sku表
    @Autowired
    private ProductSkuMapper productSkuMapper;

    //注入商品sku属性表
    @Autowired
    private ProductDetailsMapper productDetailsMapper;


    /**
     * 分页查询产品
     *
     * @param page       分页数
     * @param limit      每页记录数
     * @param productDto 商品搜索条件
     * @return
     */
    @Override
    public PageInfo<Product> findByPage(Integer page, Integer limit, ProductDto productDto) {
        //使用分页插件进行分页
        PageHelper.startPage(page, limit);
        //自定义查询：根据产品搜索条件进行查询
        List<Product> productList = productMapper.findByPage(productDto);
        //将查询集合放入分页信息中
        PageInfo<Product> pageInfo = new PageInfo<>(productList);
        //返回分页信息
        return pageInfo;
    }

    /**
     * 自定义方法：保存商品数据
     * <p>
     * 思路：
     * 1.前端提交过来的数据，包含了SPU的基本数据，SKU的列表数据，商品详情数据。
     * 2.后端可以直接使用Product接收请求参数，但是需要扩展对应的属性。
     * 3、保存数据的时候需要操作三张表：product：商品表、product_sku：商品sku表、product_detail：商品详情数据表。
     *
     * @param product 商品类
     */
    @Transactional//进行事务管理
    @Override
    public void save(Product product) {
        //1.保存商品基本信息 product表
        //设置上架状态为0，初始值
        product.setStatus(0);
        //设置审核状态为0，初始值
        product.setAuditStatus(0);
        //保存商品数据
        productMapper.save(product);

        //2.获取商品sku列表集合，获取sku信息，product_sku表
        List<ProductSku> productSkuList = product.getProductSkuList();//获取sku列表集合
        for (int i = 0; i < productSkuList.size(); ++i) {
            ProductSku productSku = productSkuList.get(i);

            //设置商品sku的字段
            //商品编号
            productSku.setSkuCode(product.getId() + "_" + i);
            //商品id
            productSku.setProductId(product.getId());
            //skuName
            productSku.setSkuName(product.getName() + productSku.getSkuSpec());
            //销量
            productSku.setSaleNum(0);
            //线上状态
            productSku.setStatus(0);
            //保存商品sku信息
            productSkuMapper.save(productSku);
        }

        //3.保存商品详情数据 product_details表
        ProductDetails productDetails = new ProductDetails();//新建商品详情数据类,用于存储商品详情数据
        productDetails.setProductId(product.getId());//设置唯一标识
        productDetails.setImageUrls(product.getDetailsImageUrls());//设置图片详情
        //保存商品详情数据
        productDetailsMapper.save(productDetails);

    }

    /**
     * 根据商品id查询商品信息
     * <p>
     * 该方法通过商品的唯一标识 `id`，从数据库中查询商品基本信息、SKU数据以及商品详情数据。
     * <p>
     * 思路：查询三张表：产品表，产品sku表和产品详情表
     *
     * @param id 商品的唯一标识
     * @return 包含完整信息的商品对象，包括SKU列表和详情数据
     */
    @Override
    public Product getById(Long id) {
        //1.根据id查询商品基本信息，product表
        Product product = productMapper.findProductById(id);

        //2.根据id查询商品sku信息,product_sku表
        List<ProductSku> productSkuList = productSkuMapper.findProductSkuByProductId(id);
        //放入产品表的sku列表集合中
        product.setProductSkuList(productSkuList);

        //3.根据id删除商品详情数据,product_details
        ProductDetails productDetails = productDetailsMapper.findProductDetailsById(id);
        String imageUrls = productDetails.getImageUrls();
        //放入产品表的图片详情列表中
        product.setDetailsImageUrls(imageUrls);

        return product;
    }

    /**
     * 保存修改数据
     * <p>
     * 该方法用于更新商品相关的数据，涉及三张表：商品表、商品SKU表和商品详情表。
     * 更新逻辑包括：
     * 1. 更新商品的基本信息。
     * 2. 更新商品的SKU（库存单位）列表信息。
     * 3. 更新商品的详情数据，包括详情图片等扩展信息。
     *
     * @param product 包含更新数据的商品对象
     */
    @Override
    public void update(Product product) {
        // 1. 修改商品表（product 表）
        // 使用商品对象中的数据更新数据库中的商品基本信息
        productMapper.updateById(product);

        // 2. 修改商品 SKU 表（product_sku 表）
        // 遍历商品对象中的 SKU 列表，逐一更新数据库中对应的 SKU 数据
        List<ProductSku> productSkuList = product.getProductSkuList();
        for (ProductSku productSku : productSkuList) {
            productSkuMapper.updateById(productSku);
        }

        // 3. 修改商品详情表（product_detail 表）
        // 从商品对象中获取详情图片 URL，并更新到商品详情表中
        String detailsImageUrls = product.getDetailsImageUrls();
        // 根据商品 ID 查询商品详情表中的当前记录
        ProductDetails productDetails = productDetailsMapper.findProductDetailsById(product.getId());
        // 更新商品详情表中的图片 URL 字段
        productDetails.setImageUrls(detailsImageUrls);
        // 保存更新后的商品详情数据
        productDetailsMapper.updateById(productDetails);
    }

    /**
     * 根据id删除商品
     * @param id
     */
    @Override
    public void deleteById(Long id) {
        //1.根据商品id删除product表
        productMapper.deleteById(id);

        //2.根据商品id删除product_sku表
        productSkuMapper.deleteByProductId(id);

        //3.根据商品id删除product_details表
        productDetailsMapper.deleteByProductId(id);

    }

    /**
     * 商品审核接口
     *
     * 该方法用于更新商品的审核状态和审核结果信息。
     * 审核通过时，将审核状态设置为 1，并添加“审核通过”的消息；
     * 审核不通过时，将审核状态设置为 -1，并添加“审核不通过”的消息。
     *
     * @param id 商品的唯一标识 ID
     * @param auditStatus 审核状态：1 表示通过，-1表示不通过
     */
    @Override
    public void updateAuditStatus(Long id, Integer auditStatus) {
        // 创建一个新的 Product 对象，用于封装需要更新的数据
        Product product = new Product();
        product.setId(id); // 设置商品的唯一标识 ID

        // 判断审核状态，根据状态设置审核结果信息
        if (auditStatus == 1) {
            // 如果审核通过
            product.setAuditStatus(1); // 设置审核状态为通过（1）
            product.setAuditMessage("审核通过"); // 设置审核消息为“审核通过”
        } else {
            // 如果审核不通过
            product.setAuditStatus(-1); // 设置审核状态为不通过（-1）
            product.setAuditMessage("审核不通过"); // 设置审核消息为“审核不通过”
        }

        // 调用数据访问层方法，将更新的数据写入数据库
        productMapper.updateById(product);
    }

    /**
     * 商品上下架接口
     *
     * 该方法用于更新商品的上下架状态：
     * - 上架时，将状态设置为 1；
     * - 下架时，将状态设置为 -1。
     *
     * @param id 商品的唯一标识 ID
     * @param status 商品上下架状态：1 表示上架，其他值表示下架
     */
    @Override
    public void updateStatus(Long id, Integer status) {
        // 创建一个新的 Product 对象，用于封装需要更新的上下架状态
        Product product = new Product();
        product.setId(id); // 设置商品的唯一标识 ID

        // 判断上下架状态，并设置对应的状态值
        if (status == 1) {
            // 如果商品状态为上架
            product.setStatus(1); // 设置状态为上架（1）
        } else {
            // 如果商品状态为下架
            product.setStatus(-1); // 设置状态为下架（-1）
        }

        // 调用数据访问层方法，将更新的数据写入数据库
        productMapper.updateById(product);
    }



}
